const os = require('os');

/**
 * 性能监控中间件
 * 记录请求响应时间和系统资源使用情况
 */
function performanceMonitor(req, res, next) {
  const startTime = Date.now();
  const startMemory = process.memoryUsage();

  // 记录请求开始时间
  req.startTime = startTime;

  // 重写res.end方法以记录响应时间
  const originalEnd = res.end;
  res.end = function (...args) {
    const endTime = Date.now();
    const responseTime = endTime - startTime;
    const endMemory = process.memoryUsage();

    // 计算内存使用变化
    const memoryDiff = {
      rss: endMemory.rss - startMemory.rss,
      heapUsed: endMemory.heapUsed - startMemory.heapUsed,
      heapTotal: endMemory.heapTotal - startMemory.heapTotal,
      external: endMemory.external - startMemory.external
    };

    // 获取系统信息
    const cpuUsage = process.cpuUsage();
    const loadAverage = os.loadavg();

    // 性能日志
    const performanceLog = {
      timestamp: new Date().toISOString(),
      method: req.method,
      url: req.originalUrl,
      statusCode: res.statusCode,
      responseTime: `${responseTime}ms`,
      memory: {
        current: {
          rss: `${Math.round(endMemory.rss / 1024 / 1024)}MB`,
          heapUsed: `${Math.round(endMemory.heapUsed / 1024 / 1024)}MB`,
          heapTotal: `${Math.round(endMemory.heapTotal / 1024 / 1024)}MB`
        },
        diff: {
          rss: `${Math.round(memoryDiff.rss / 1024 / 1024)}MB`,
          heapUsed: `${Math.round(memoryDiff.heapUsed / 1024 / 1024)}MB`
        }
      },
      system: {
        cpuUser: `${Math.round(cpuUsage.user / 1000)}ms`,
        cpuSystem: `${Math.round(cpuUsage.system / 1000)}ms`,
        loadAverage: loadAverage.map(load => load.toFixed(2))
      }
    };

    // 根据响应时间和状态码决定日志级别
    if (responseTime > 3000 || res.statusCode >= 500) {
      console.error('🚨 性能警告:', performanceLog);
    } else if (responseTime > 1000 || res.statusCode >= 400) {
      console.warn('⚠️ 性能注意:', performanceLog);
    } else if (process.env.NODE_ENV === 'development' && process.env.ENABLE_PERFORMANCE_LOGS === 'true') {
      console.log('📊 性能监控:', performanceLog);
    }

    // 设置响应头
    res.set('X-Response-Time', `${responseTime}ms`);
    res.set('X-Memory-Usage', `${Math.round(endMemory.heapUsed / 1024 / 1024)}MB`);

    // 调用原始的end方法
    originalEnd.apply(this, args);
  };

  next();
}

/**
 * 慢查询监控中间件
 * 专门监控数据库查询性能
 */
function slowQueryMonitor(threshold = 1000) {
  return (req, res, next) => {
    const originalJson = res.json;

    res.json = function (data) {
      const responseTime = Date.now() - req.startTime;

      // 如果响应时间超过阈值，记录慢查询
      if (responseTime > threshold) {
        console.warn('🐌 慢查询检测:', {
          timestamp: new Date().toISOString(),
          method: req.method,
          url: req.originalUrl,
          responseTime: `${responseTime}ms`,
          query: req.query,
          body: req.method !== 'GET' ? req.body : undefined,
          threshold: `${threshold}ms`
        });
      }

      return originalJson.call(this, data);
    };

    next();
  };
}

/**
 * 内存泄漏监控
 */
function memoryLeakMonitor() {
  let lastMemoryUsage = process.memoryUsage();
  let requestCount = 0;

  return (req, res, next) => {
    requestCount++;

    // 每100个请求检查一次内存使用情况
    if (requestCount % 100 === 0) {
      const currentMemory = process.memoryUsage();
      const memoryGrowth = {
        rss: currentMemory.rss - lastMemoryUsage.rss,
        heapUsed: currentMemory.heapUsed - lastMemoryUsage.heapUsed,
        heapTotal: currentMemory.heapTotal - lastMemoryUsage.heapTotal
      };

      // 如果内存增长超过50MB，发出警告
      if (memoryGrowth.heapUsed > 50 * 1024 * 1024) {
        console.warn('🧠 内存增长警告:', {
          timestamp: new Date().toISOString(),
          requestCount,
          memoryGrowth: {
            rss: `${Math.round(memoryGrowth.rss / 1024 / 1024)}MB`,
            heapUsed: `${Math.round(memoryGrowth.heapUsed / 1024 / 1024)}MB`,
            heapTotal: `${Math.round(memoryGrowth.heapTotal / 1024 / 1024)}MB`
          },
          currentMemory: {
            rss: `${Math.round(currentMemory.rss / 1024 / 1024)}MB`,
            heapUsed: `${Math.round(currentMemory.heapUsed / 1024 / 1024)}MB`,
            heapTotal: `${Math.round(currentMemory.heapTotal / 1024 / 1024)}MB`
          }
        });
      }

      lastMemoryUsage = currentMemory;
    }

    next();
  };
}

/**
 * API限流中间件
 */
function rateLimiter(windowMs = 15 * 60 * 1000, max = 100) {
  const requests = new Map();

  return (req, res, next) => {
    const key = req.ip || req.connection.remoteAddress;
    const now = Date.now();
    const windowStart = now - windowMs;

    // 清理过期的请求记录
    if (requests.has(key)) {
      const userRequests = requests.get(key).filter(time => time > windowStart);
      requests.set(key, userRequests);
    } else {
      requests.set(key, []);
    }

    const userRequests = requests.get(key);

    // 检查是否超过限制
    if (userRequests.length >= max) {
      return res.status(429).json({
        success: false,
        message: '请求过于频繁，请稍后再试',
        retryAfter: Math.ceil(windowMs / 1000)
      });
    }

    // 记录当前请求
    userRequests.push(now);

    // 设置响应头
    res.set({
      'X-RateLimit-Limit': max,
      'X-RateLimit-Remaining': max - userRequests.length,
      'X-RateLimit-Reset': new Date(now + windowMs).toISOString()
    });

    next();
  };
}

/**
 * 健康检查端点
 */
function healthCheck(req, res) {
  const memoryUsage = process.memoryUsage();
  const uptime = process.uptime();
  const loadAverage = os.loadavg();

  const health = {
    status: 'healthy',
    timestamp: new Date().toISOString(),
    uptime: `${Math.floor(uptime / 60)}分${Math.floor(uptime % 60)}秒`,
    memory: {
      rss: `${Math.round(memoryUsage.rss / 1024 / 1024)}MB`,
      heapUsed: `${Math.round(memoryUsage.heapUsed / 1024 / 1024)}MB`,
      heapTotal: `${Math.round(memoryUsage.heapTotal / 1024 / 1024)}MB`,
      external: `${Math.round(memoryUsage.external / 1024 / 1024)}MB`
    },
    system: {
      platform: os.platform(),
      arch: os.arch(),
      cpus: os.cpus().length,
      loadAverage: loadAverage.map(load => load.toFixed(2)),
      freeMemory: `${Math.round(os.freemem() / 1024 / 1024)}MB`,
      totalMemory: `${Math.round(os.totalmem() / 1024 / 1024)}MB`
    }
  };

  // 检查内存使用是否过高
  const memoryUsagePercent = (memoryUsage.heapUsed / memoryUsage.heapTotal) * 100;
  if (memoryUsagePercent > 90) {
    health.status = 'warning';
    health.warnings = ['内存使用率过高'];
  }

  // 检查负载是否过高
  if (loadAverage[0] > os.cpus().length * 0.8) {
    health.status = 'warning';
    health.warnings = health.warnings || [];
    health.warnings.push('系统负载过高');
  }

  res.json(health);
}

module.exports = {
  performanceMonitor,
  slowQueryMonitor,
  memoryLeakMonitor,
  rateLimiter,
  healthCheck
};
